home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics Plus
/
Graphics Plus.iso
/
msdos
/
utils
/
cad3d2ra.zoo
/
cad3d2raw.c
next >
Wrap
C/C++ Source or Header
|
1994-04-05
|
11KB
|
410 lines
/*
* cad3d2raw - Atari CAD-3D 2.0 to RAW triangles
* $Id: cad3d2raw.c,v 1.2 1994/04/05 14:36:21 herborth Exp $
*
* Chris Herborth
* March 5/94
*
* This program will convert a CAD-3D file into a dump of RAW triangles
* suitable for processing with raw2pov or other programs.
*
* Todo: include lighting information in the RAW dump (if there's some
* way raw2pov can deal with it)
*
* $Log: cad3d2raw.c,v $
* Revision 1.2 1994/04/05 14:36:21 herborth
* Fixed bogus usage message.
*
* Revision 1.1 1994/03/14 15:23:37 herborth
* Initial revision
*
*/
#include <unistd.h> /* needed for malloc() */
#include <stdio.h> /* input/output stuff */
#include <string.h> /* needed for strrchr() */
#include <stdlib.h> /* needed for malloc() */
#include "cad3d2raw.h" /* function prototypes, etc */
#include "cad3dobj.h" /* CAD-3D file structures */
short cad3dobj_as_raw( FILE *fp, const CAD3D_OBJECT *obj,
const CAD3D_HEADER *head );
#define VERBOSE 0x0001 /* verbose flag */
#define NOISY 0x0002 /* debug flag */
#define NO_OUTFILE 0x0004 /* no output file specified flag */
#define COLOURS 0x0008 /* use CAD-3D colours in file */
#define COLOUR_BASE 0x0010 /* use colour group base */
#define BOZO 0x8000 /* Quit ASAP, bad options given */
short flags = 0;
int main( int argc, char **argv )
{
char *input_filename = "",
*output_filename = "";
FILE *input_stream,
*output_stream;
short loop,
retval; /* A spot to stick return values */
CAD3D_HEADER header;
CAD3D_OBJECT *objects;
/* Check to see if the user doesn't know what they're doing... */
if( argc < 2 )
{
usage();
return 1;
}
/* Parse the command-line arguments... */
for( loop = 1; loop < argc; loop++ )
{
char *arg;
arg = argv[loop];
if( arg[0] == '-' )
switch( arg[1] )
{
case 'V':
version();
break;
case 'h':
case '?':
usage();
break;
case 'c':
flags |= COLOURS;
break;
case 'b':
flags |= COLOUR_BASE;
break;
case 'v':
flags |= VERBOSE;
break;
case 'd':
flags |= ( NOISY | VERBOSE );
break;
default:
fprintf( stderr, "Unknown option \"%s\"!\n", arg );
flags |= BOZO;
break;
}
else
if( strlen( input_filename ) == 0 )
input_filename = arg;
else
if( strlen( output_filename ) == 0 )
output_filename = arg;
else
{
fprintf( stderr, "Extra file argument: %s\n", arg );
flags |= BOZO;
}
}
/* Check to see if the user entered some mutant args... */
if( flags & BOZO )
{
fprintf( stderr, "Error parsing arguments.\n" );
return 1;
}
/* Check to see if we've got an input file... */
if( strlen( input_filename ) == 0 )
{
fprintf( stderr, "No input filename specified.\n" );
return 1;
}
/* Check to see if we need to create an output filename... */
if( strlen( output_filename ) == 0 )
{
flags |= NO_OUTFILE;
output_filename = make_outfile( input_filename, output_extension );
}
if( flags & NOISY )
{
fprintf( stderr, "Debugging messages enabled.\n" );
if( flags & VERBOSE )
fprintf( stderr, "Verbose messages enabled.\n" );
fprintf( stderr, "Input filename: %s\n", input_filename );
if( flags & NO_OUTFILE )
fprintf( stderr, "Program will create an output filename: %s.\n",
output_filename );
else
fprintf( stderr, "Output filename: %s\n", output_filename );
if( flags & COLOURS )
{
fprintf( stderr, "Using triangle colours.\n" );
fprintf( stderr, "(Will produce a Fractint RAW file.)\n" );
}
if( flags & COLOUR_BASE )
{
fprintf( stderr, "Using triangle base colours.\n" );
fprintf( stderr, "(Will produce a Fractint RAW file.)\n" );
}
}
/* Open our input/output files */
input_stream = fopen( input_filename, "rb" );
if( input_stream == NULL )
{
fprintf( stderr, "Can't open input file: %s\n", input_filename );
return 1;
}
output_stream = fopen( output_filename, "w" );
if( output_stream == NULL )
{
fprintf( stderr, "Can't open output file: %s\n", output_filename );
fclose( input_stream );
return 1;
}
if( flags & VERBOSE )
fprintf( stderr, "Reading file header...\n" );
retval = get_cad3d_header( input_stream, &header );
if( retval != 0 )
switch( retval )
{
case -1:
fprintf( stderr, "Error reading file: %s\n", output_filename );
fclose( input_stream );
fclose( output_stream );
return 1;
/* break; */
case -2:
fprintf( stderr, "Bad CAD-3D file id: %x\n", header.file_id );
fclose( input_stream );
fclose( output_stream );
return 1;
/* break; */
default:
fprintf( stderr, "Unknown error code %d from get_cad3d_header!\n",
retval );
break;
}
if( flags & NOISY )
retval = dump_cad3d_header( stderr, &header );
/* Load the objects from the 3d2 file... */
if( flags & VERBOSE )
fprintf( stderr, "Reading objects...\n" );
objects = (CAD3D_OBJECT *)malloc( header.num_objects * sizeof( CAD3D_OBJECT ) );
if( objects == NULL )
{
fprintf( stderr, "Can't allocate memory for objects!\n" );
fclose( input_stream );
fclose( output_stream );
return 2;
}
for( loop = 0; loop < header.num_objects; loop++ )
{
retval = get_cad3d_object( input_stream, &(objects[loop]) );
if( retval != 0 )
switch( retval )
{
case -1:
fprintf( stderr, "Error reading object %d!\n", loop );
fclose( input_stream );
fclose( output_stream );
return 1;
/* break; */
case -2:
fprintf( stderr, "Can't allocate memory for vertices in object %d!\n",
loop );
fclose( input_stream );
fclose( output_stream );
return 2;
/* break; */
case -3:
fprintf( stderr, "Error reading %d vertices for object %d!\n",
objects[loop].num_vertices, loop );
fclose( input_stream );
fclose( output_stream );
return 1;
/* break; */
case -4:
fprintf( stderr, "Can't allocate memory for triangles in object %d!\n",
loop );
fclose( input_stream );
fclose( output_stream );
return 2;
/* break; */
case -5:
fprintf( stderr, "Error reading %d triangles for object %d!\n",
objects[loop].num_triangles, loop );
fclose( input_stream );
fclose( output_stream );
return 1;
/* break; */
default:
fprintf( stderr, "Unknown error code %d from get_cad3d_object!\n",
retval );
break;
}
if( flags & VERBOSE )
fprintf( stderr, "Loaded object %d, \"%s\" with %d vertices and %d triangles...\n",
loop, objects[loop].name, objects[loop].num_vertices,
objects[loop].num_triangles );
if( flags & NOISY )
retval = dump_cad3d_object( stderr, &(objects[loop]) );
}
/* Now that we've loaded the objects, dump them to a RAW file. */
fprintf( output_stream, "{ RAW file created with cad3d2raw }\n\n" );
for( loop = 0; loop < header.num_objects; loop++ )
{
if( flags & NOISY )
fprintf( stderr, "Dumping object %d, \"%s\", to RAW...\n",
loop, objects[loop].name );
retval = cad3dobj_as_raw( output_stream, &(objects[loop]), &header );
if( retval != 0 )
switch( retval )
{
case -1:
fprintf( stderr, "Bad stream or object in cad3dobj_as_raw!\n" );
fflush( output_stream );
fclose( input_stream );
fclose( output_stream );
return 1;
/* break; */
default:
fprintf( stderr, "Unknown return value %d from cad3dobj_as_raw!\n",
retval );
break;
}
}
fflush( output_stream );
fclose( input_stream );
fclose( output_stream );
/* All's well that ends well... */
return 0;
}
short cad3dobj_as_raw( FILE *fp, const CAD3D_OBJECT *obj,
const CAD3D_HEADER *head )
{
unsigned short loop;
short retval;
RGB_TRIAD colour;
char tmp[9];
if( fp == NULL || obj == NULL )
return -1;
if( flags & NOISY )
fprintf( stderr, "Dumping %s, %d triangles...\n", obj->name,
obj->num_triangles );
if( flags & VERBOSE )
fprintf( stderr, "Dumping %s...\n", obj->name );
/* Fiddle with the object name, since raw2pov dies if you have */
/* spaces in object names... */
strcpy( tmp, obj->name );
for( loop = 0; loop < strlen( tmp ); loop++ )
if( tmp[loop] == ' ' ) /* should probably be iswhite() */
tmp[loop] = '_';
fprintf( fp, "\"%s\"\n", tmp );
for( loop = 0; loop < obj->num_triangles; loop++ )
{
if( flags & COLOURS )
{
retval = obj->triangles[loop].colour_edge & 0x00ff;
retval = atari2rgb( head->obj_palette[retval],
&colour );
fprintf( fp, "%f %f %f\n", colour.red, colour.green, colour.blue );
}
if( flags & COLOUR_BASE )
{
retval = cad3d_triangle_colour( head, &(obj->triangles[loop]) );
retval = atari2rgb( retval, &colour );
fprintf( fp, "%f %f %f\n", colour.red, colour.green, colour.blue );
}
fprintf( fp, "%f %f %f\n",
(float)(obj->vertices[obj->triangles[loop].index_a].x)/100.0,
(float)(obj->vertices[obj->triangles[loop].index_a].y)/100.0,
(float)(obj->vertices[obj->triangles[loop].index_a].z)/100.0 );
fprintf( fp, "%f %f %f\n",
(float)(obj->vertices[obj->triangles[loop].index_b].x)/100.0,
(float)(obj->vertices[obj->triangles[loop].index_b].y)/100.0,
(float)(obj->vertices[obj->triangles[loop].index_b].z)/100.0 );
fprintf( fp, "%f %f %f\n\n",
(float)(obj->vertices[obj->triangles[loop].index_c].x)/100.0,
(float)(obj->vertices[obj->triangles[loop].index_c].y)/100.0,
(float)(obj->vertices[obj->triangles[loop].index_c].z)/100.0 );
}
fprintf( fp, "\n" );
return 0;
}
char *make_outfile( const char *infile, const char *outext )
{
char *tmp, *exten;
if( flags & NOISY )
{
fprintf( stderr, "make_outfile[%d]: infile = %s\n", __LINE__, infile );
fprintf( stderr, "make_outfile[%d]: outext = %s\n", __LINE__, outext );
}
tmp = (char *)malloc( strlen( infile ) + strlen( outext ) + 1 );
strcpy( tmp, infile );
if( flags & NOISY )
fprintf( stderr, "make_outfile[%d]: tmp = %s\n", __LINE__, tmp );
exten = strrchr( tmp, (int)'.' );
if( exten == NULL )
strcat( tmp, "." );
else
{
if( flags & NOISY )
fprintf( stderr, "make_outfile[%d]: exten = %s\n",
__LINE__, exten );
exten[1] = 0x00;
}
strcat( tmp, outext );
if( flags & NOISY )
fprintf( stderr, "make_outfile[%d]: tmp = %s\n", __LINE__, tmp );
return tmp;
}
void usage( void )
{
puts( "usage: cad3d2raw [options] input.3d2 [output.raw]\n" );
puts( " -c - use colours from CAD-3D file (makes a Fractint RAW file)" );
puts( " -b - use colour base (works better; makes a Fractint RAW file)" );
puts( " -v - verbose output" );
puts( " -d - debugging output (ie, extra-verbose)\n" );
puts( "Less useful options:" );
puts( " -h - print this message" );
puts( " -? - print this message" );
puts( " -V - print version info" );
return;
}
void version( void )
{
puts( version_info );
return;
}